package com.kc.service.impl;

import com.kc.ExceptionHandler.UndowException;
import com.kc.bean.GroundAccount;
import com.kc.bean.UserAccount;
import com.kc.bean.UserPassword;
import com.kc.service.*;
import com.kc.util.*;
import com.nimbusds.jose.JOSEException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.crypto.BadPaddingException;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.CompletableFuture;

@Service
public class RegistAndLoginImpl implements IRegistAndLogin {

    private Logger logger = LoggerFactory.getLogger(RegistAndLoginImpl.class);

    @Resource
    private IUserAccountService userAccountService;

    @Resource
    private IGroundAccountService groundAccountService;

    @Resource
    private IUserPasswordService userPasswordService;

    @Resource
    private IGroudService groudService;

    @Resource
    private ResponesBean responesBean;

    @Transactional
    @Override
    public ResponesBean register(UserAccount userAccount, String code, String password) {
        StringBuilder builder = null;
        try {
            long nowtime = System.currentTimeMillis();
            //直接查这里如果null指针报错等下直接补抓且抛自定义异常
            String rediscode = RedisUtil.getValue(userAccount.getUserPhone());
            rediscode = rediscode.substring(1,7);
            if (!rediscode.equals(code)) {
                throw new UndowException("验证么错误请重试");
            }
            builder = new StringBuilder();
//            拼接密码存进去密码表
            String PhonePassword = builder.append(userAccount.getUserPhone()).append("|").append(PasswordUtil.encryptAES(password.getBytes())).toString();
            builder.delete(0,builder.length());
            String EmialPassword = builder.append(userAccount.getUserEmial()).append("|").append(PasswordUtil.encryptAES(password.getBytes())).toString();

            UserPassword userPassword = new UserPassword();
            GroundAccount groundAccount = new GroundAccount();

            //设置用户的各种信息
            userAccount.setUserId(UuidCreate.getUUID());
            DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss");
            userAccount.setCreateTime(dateTimeFormatter.format(LocalDateTime.now()));
            userAccount.setStatus("1");
            userAccount.setUserUniqueIdIdentifier(UuidCreate.getUUID());
            userAccount.setAccountAvatar("默认头像");
            userPassword.setPhone(PhonePassword);
            userPassword.setEmail(EmialPassword);
            userPassword.setAccountId(userAccount.getUserId());
            groundAccount.setAccountId(userAccount.getUserId());

//            异步插入到数据库
            CompletableFuture<Integer> AccountThread = userAccountService.inst(userAccount);
            CompletableFuture<Integer> PasswordThread = userPasswordService.inst(userPassword);
            CompletableFuture<Integer> GroudThread = groundAccountService.instGroudAccount(groundAccount);
            CompletableFuture.allOf(AccountThread, PasswordThread, GroudThread).join();

            long endtime = System.currentTimeMillis();

            responesBean.setAll(200, "注册成功" + (endtime - nowtime), null);
            return responesBean;
        } catch (NullPointerException e) {
            responesBean.setAll(400,"验证码错误，请重新输入",null);
            return responesBean;
        } catch (NoSuchAlgorithmException | InvalidAlgorithmParameterException | NoSuchPaddingException | BadPaddingException | IllegalBlockSizeException | InvalidKeyException e) {
            throw new UndowException("密码加密失败请联系管理员"+e.getMessage());
        }catch (DataIntegrityViolationException e){
            responesBean.setAll(400,"注册资料为空",null);
            return responesBean;
        }
    }


    @Override
    public ResponesBean login(String phone, String password) {
        try {

            String id = userPasswordService.getAccountId(phone, password);

            UserAccount account = userAccountService.getUserAccount(id);
            

            //获取用户的角色
            StringBuilder builder = new StringBuilder();
            List<String> groud = groudService.GetAllRole(groundAccountService.GetGroudId(account.getUserId()));
            for (int i=0;i<groud.size();i++){
                builder.append(groud.get(i)).append(",");
            }
            String role = builder.deleteCharAt(builder.lastIndexOf(",")).toString();

            String token = JWTutil.craateToken(role,account.getUserUniqueIdIdentifier(),UuidCreate.getUUID());
            HashMap<String,Object> hashMap = new HashMap<String, Object>();
            hashMap.put("AcessToken",token);
            hashMap.put("Account",account);
            responesBean.setAll(200,"登陆成功，token和用户信息如下:",hashMap);
            return responesBean;
        } catch (NoSuchAlgorithmException | InvalidKeyException | InvalidAlgorithmParameterException | NoSuchPaddingException | BadPaddingException | IllegalBlockSizeException e) {
            logger.error("密码加错失败请查看信息:" + e.getMessage());
            throw new UndowException("服务器发生错误请联系管理员");
        } catch (NullPointerException e) {
            throw new UndowException("没有找到该用户");
        } catch (JOSEException e) {
            logger.error(e.getMessage());
            throw new UndowException("登陆失败，请重试，还是如此请联系管理员。");
        }
    }
}